package rhc.common.data.dao;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import com.mongodb.CommandResult;
import com.mongodb.WriteResult;

import rhc.common.entity.AbstractDocument;
import rhc.common.util.NullUtil;

@Repository
public class SuperDao {

	
	public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * 每次查询最多传递的列表个数
	 */
	public static final int MAX_CHECK_LIST_NUM=30;
	
	
	public static SuperDao superDao;
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	protected Logger logger=Logger.getLogger(getClass());
	
	
	@PostConstruct
	public void init(){
		superDao=this;
	}
	
	
//	/** 无条件获取，同时需要哪些字段
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getT(Class<T> t,String...columns){
//		long begin=System.currentTimeMillis();
//		List<T> allTs=null;
//		
//		Query query = new Query();
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().include(c);
//			}
//		}
//		
//		allTs=mongoTemplate.find(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==allTs?0:allTs.size())+"，消耗时间："+(System.currentTimeMillis()-begin)/1000+"秒");
//		
//		return allTs;
//	}
//	
//	/** 无条件获取，同时不需要哪些字段
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTExcludeColumn(Class t,String...columns){
//		long begin=System.currentTimeMillis();
//		List<T> allTs=null;
//		
//		Query query = new Query();
//		
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().exclude(c);
//			}
//		}
//		
//		allTs=mongoTemplate.find(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==allTs?0:allTs.size())+"，消耗时间："+(System.currentTimeMillis()-begin)/1000+"秒");
//		
//		return allTs;
//	}
//	
//	/** 字段值
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTByColumns(Class<T> t,String column,Collection ids,String...columns){
//		if(null==ids || ids.size()==0){
//			return null;
//		}
//		
//		return getTByColumns(t,column,ids.toArray(),columns);
//	}
//	
//	/** 根据字段值获取，同时需要哪些字段
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTByColumns(Class<T> t,String column,Object[] ids,String...columns){
//		if(null==ids || ids.length==0){
//			return null;
//		}
//		long begin=System.currentTimeMillis();
//		int totalSize=ids.length;
//		List<T> allTs=null;
//		//当字段值个数超过MAX_CHECK_LIST_NUM时分多次查询
//		if(totalSize>SuperDao.MAX_CHECK_LIST_NUM){
//			
//			allTs=new LinkedList<T>();
//			Object[][] splitIdsList=NormalUtil.splitAry(ids, SuperDao.MAX_CHECK_LIST_NUM);
//			
//			for(Object[] nt:splitIdsList){
//				Query query = new Query();
//				query.addCriteria(Criteria.where(column).in(nt));
//				if(null!=columns){
//					for(String c:columns){
//						query.fields().include(c);
//					}
//				}
//				List<T> Ts=mongoTemplate.find(query, t);
//				if(null == Ts || Ts.size()==0){
//					continue;
//				}
//				allTs.addAll(Ts);
//			}
//		}else{
//			Query query = new Query();
//			query.addCriteria(Criteria.where(column).in(ids));
//			
//			if(null!=columns){
//				for(String c:columns){
//					query.fields().include(c);
//				}
//			}
//			
//			allTs=mongoTemplate.find(query, t);
//		}
//		
//		Query query=new Query(Criteria.where(column).in(ids));
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().include(c);
//			}
//		}
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==allTs?0:allTs.size())+"，消耗时间："+(System.currentTimeMillis()-begin)/1000+"秒");
//		
//		
//		return allTs;
//	}
//	
//	/** 根据字段值获取，同时不需要哪些字段
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTByColumnsExcludeColumn(Class t,String column,Collection ids,String...columns){
//		if(null==ids || ids.size()==0){
//			return null;
//		}
//		
//		return getTByColumnsExcludeColumn(t,column,ids.toArray(),columns);
//	}
//	
//	/** 根据字段值获取，同时不需要哪些字段
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTByColumnsExcludeColumn(Class t,String column,Object[] ids,String...columns){
//		if(null==ids || ids.length==0){
//			return null;
//		}
//		long begin=System.currentTimeMillis();
//		int totalSize=ids.length;
//		List<T> allTs=null;
//		//当字段值个数超过MAX_CHECK_LIST_NUM时分多次查询
//		if(totalSize>SuperDao.MAX_CHECK_LIST_NUM){
//			
//			allTs=new LinkedList<T>();
//			Object[][] splitIdsList=NormalUtil.splitAry(ids, SuperDao.MAX_CHECK_LIST_NUM);
//			
//			for(Object[] nt:splitIdsList){
//				Query query = new Query();
//				query.addCriteria(Criteria.where(column).in(nt));
//				if(null!=columns){
//					for(String c:columns){
//						query.fields().exclude(c);
//					}
//				}
//				List<T> Ts=mongoTemplate.find(query, t);
//				if(null == Ts || Ts.size()==0){
//					continue;
//				}
//				allTs.addAll(Ts);
//			}
//		}else{
//			Query query = new Query();
//			query.addCriteria(Criteria.where(column).in(ids));
//			
//			if(null!=columns){
//				for(String c:columns){
//					query.fields().exclude(c);
//				}
//			}
//			
//			allTs=mongoTemplate.find(query, t);
//		}
//		
//		Query query=new Query(Criteria.where(column).in(ids));
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().exclude(c);
//			}
//		}
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==allTs?0:allTs.size())+"，消耗时间："+(System.currentTimeMillis()-begin)/1000+"秒");
//		
//		return allTs;
//	}
//	
//	/** 字段值
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTByColumn(Class<T> t,String column,Object columnValue,String...columns){
//		
//		Query query = new Query();
//		query.addCriteria(Criteria.where(column).is(columnValue));
//		
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().include(c);
//			}
//		}
//		
//		logger.debug("开始查询，查询条件为："+query.toString());
//		
//		long currentTime=System.currentTimeMillis();
//		
//		List<T> tList=mongoTemplate.find(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==tList?0:tList.size())+"，消耗时间："+(System.currentTimeMillis()-currentTime)/1000+"秒");
//		
//		
//		return tList;
//	}
//	
//	/** 字段值
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> List<T> getTByColumnExcludeColumn(Class t,String column,Object columnValue,String...excludeColumns){
//		
//		Query query = new Query();
//		query.addCriteria(Criteria.where(column).is(columnValue));
//		
//		if(null!=excludeColumns){
//			for(String c:excludeColumns){
//				query.fields().exclude(c);
//			}
//		}
//		
//		logger.debug("开始查询，查询条件为："+query.toString());
//		
//		long currentTime=System.currentTimeMillis();
//		
//		List<T> tList=mongoTemplate.find(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==tList?0:tList.size())+"，消耗时间："+(System.currentTimeMillis()-currentTime)/1000+"秒");
//		
//		
//		return tList;
//	}
//	
//	/** 字段值
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> T getOneTByColumn(Class<T> t,String column,Object columnValue,String...columns){
//		
//		Query query = new Query();
//		query.addCriteria(Criteria.where(column).is(columnValue));
//		
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().include(c);
//			}
//		}
//		
//		logger.debug("开始查询，查询条件为："+query.toString());
//		
//		long currentTime=System.currentTimeMillis();
//		
//		T data=mongoTemplate.findOne(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==data?0:1)+"，消耗时间："+(System.currentTimeMillis()-currentTime)/1000+"秒");
//		
//		
//		return data;
//	}
//	
//	/** 字段值
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> T getOneT(Class<T> t,Criteria[] criterias,Sort sort,String...columns){
//		long currentTime=System.currentTimeMillis();
//		
//		Query query = new Query();
//		
//		if(null!=columns){
//			for(String c:columns){
//				query.fields().include(c);
//			}
//		}
//		
//		if(null != criterias){
//			for(Criteria c:criterias){
//				query.addCriteria(c);
//			}
//		}
//		
//		query=sort==null?query:query.with(sort);
//		
//		logger.debug("开始查询，查询条件为："+query.toString());
//		
//		T data=mongoTemplate.findOne(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==data?0:1)+"，消耗时间："+(System.currentTimeMillis()-currentTime)/1000+"秒");
//		
//		
//		return data;
//	}
//	
//	/** 字段值
//	 * @param column 字段名
//	 * @param ids 字段值
//	 * @param columns 获取哪些字段
//	 * @return
//	 */
//	public <T> T getOneTExcludeColumn(Class<T> t,Criteria[] criterias,Sort sort,String...excludeColumns){
//		long currentTime=System.currentTimeMillis();
//		
//		Query query = new Query();
//		
//		if(null!=excludeColumns){
//			for(String c:excludeColumns){
//				query.fields().exclude(c);
//			}
//		}
//		
//		if(null != criterias){
//			for(Criteria c:criterias){
//				query.addCriteria(c);
//			}
//		}
//		
//		query=sort==null?query:query.with(sort);
//		
//		logger.debug("开始查询，查询条件为："+query.toString());
//		
//		
//		T data=mongoTemplate.findOne(query, t);
//		
//		logger.debug("结束查询，查询条件为："+query.toString()+",查询结束，获取到的记录数为"+(null==data?0:1)+"，消耗时间："+(System.currentTimeMillis()-currentTime)/1000+"秒");
//		
//		return data;
//	}
//	
//
//	
//	/**通过键值删除文档
//	 * @param _class
//	 * @param column
//	 * @param value
//	 */
//	public <T> void deleteTByColumn(Class<? extends T> _class,String column,Object value){
//		if(StringUtils.isEmpty(column) || null == value){
//			return;
//		}
//		Query query=new Query(Criteria.where(column).is(value));
//		delete(_class,query);
//	}
//	
//	/**删除符合条件的文档
//	 * @param _class
//	 * @param query
//	 */
//	public <T> void delete(Class<? extends T> _class,Query query){
//		mongoTemplate.remove(query, _class);
//	}
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	/**查询某一列值符合条件的第一个文档并不提取某些列
//	 * @param _class
//	 * @param column
//	 * @param columnValue
//	 * @param excludeColumns
//	 * @return
//	 */
//	public <T> T getOneTByColumnExcludeColumn(Class<T> _class,String column,Object columnValue,String...excludeColumns){
//		Query query=this.getIsQuery(this.getExcludeColumnQuery(null, excludeColumns), column, columnValue);
//		return this.getOneT(mongoTemplate, query, _class);
//	}
//	
//	/**查询某一列值符合条件的第一个文档并只提取某些列
//	 * @param _class
//	 * @param column
//	 * @param columnValue
//	 * @param includeColumns
//	 * @return
//	 */
//	public <T> T getOneTByColumnIncludeColumn(Class<T> _class,String column,Object columnValue,String...includeColumns){
//		Query query=this.getIsQuery(this.getIncludeColumnQuery(null, includeColumns), column, columnValue);
//		return this.getOneT(mongoTemplate, query, _class);
//	}
//	
//	
//	
//	
//	
//	/**查询某一列值符合条件的第一个文档并不提取某些列
//	 * @param _class
//	 * @param column
//	 * @param columnValue
//	 * @param excludeColumns
//	 * @return
//	 */
//	public <T> T getOneTByColumnsExcludeColumn(Class<T> _class,String column,Object[] columnValue,String...excludeColumns){
//		Query query=this.getColumnInValueQuery(this.getExcludeColumnQuery(null, excludeColumns), column, columnValue);
//		return this.getOneT(mongoTemplate, query, _class);
//	}
//	
//	/**查询某一列值符合条件的第一个文档并只提取某些列
//	 * @param _class
//	 * @param column
//	 * @param columnValue
//	 * @param includeColumns
//	 * @return
//	 */
//	public <T> T getOneTByColumnsIncludeColumn(Class<T> _class,String column,Object[] columnValue,String...includeColumns){
//		Query query=this.getColumnInValueQuery(this.getIncludeColumnQuery(null, includeColumns), column, columnValue);
//		return this.getOneT(mongoTemplate, query, _class);
//	}
//	
//	
//	
//	
//	
//	
//	
//	
//	
//	/**根据一列的值获取 文档对象，这些对象只包含 columns 这几列
//	 * @param t
//	 * @param column
//	 * @param values
//	 * @param columns
//	 * @return
//	 */
//	public <T> List<T> getTsByColumns(Class<T> t,Sort sort,String column,Object[] values,String...columns){
//		return getTsByColumns(mongoTemplate,t,sort,column,values,columns);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象只包含 columns 这几列
//	 * @param mongoTemplate
//	 * @param t
//	 * @param column
//	 * @param values
//	 * @param columns
//	 * @return
//	 */
//	public <T> List<T> getTsByColumns(MongoTemplate mongoTemplate,Class<T> _class,Sort sort,String column,Object[] values,String...columns){
//		Query query=this.getSortQuery(this.getColumnInValueQuery(this.getIncludeColumnQuery(null, columns), column, values),sort);
//		return this.getAllT(mongoTemplate, query, _class);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象不包含 columns 这几列
//	 * @param t
//	 * @param column
//	 * @param values
//	 * @param excludeColumns
//	 * @return
//	 */
//	public <T> List<T> getTsByColumnsExcludeColumns(Class<T> t,Sort sort,String column,Object[] values,String...excludeColumns){
//		return getTsByColumnsExcludeColumns(mongoTemplate,t,sort,column,values,excludeColumns);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象不包含 columns 这几列
//	 * @param mongoTemplate
//	 * @param _class
//	 * @param column
//	 * @param values
//	 * @param excludeColumns
//	 * @return
//	 */
//	public <T> List<T> getTsByColumnsExcludeColumns(MongoTemplate mongoTemplate,Class<T> _class,Sort sort,String column,Object[] values,String...excludeColumns){
//		Query query=this.getSortQuery(this.getColumnInValueQuery(this.getExcludeColumnQuery(null, excludeColumns), column, values),sort);
//		return this.getAllT(mongoTemplate, query, _class);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象只包含 columns 这几列
//	 * @param t
//	 * @param column
//	 * @param values
//	 * @param columns
//	 * @return
//	 */
//	public <T> void getPageTByColumns(Class<T> t,Page<T> page,Sort sort,String column,Object[] values,String...columns){
//		getPageTByColumns(mongoTemplate,t,page,sort,column,values,columns);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象只包含 columns 这几列
//	 * @param mongoTemplate
//	 * @param t
//	 * @param column
//	 * @param values
//	 * @param columns
//	 * @return
//	 */
//	public <T> void getPageTByColumns(MongoTemplate mongoTemplate,Class<T> _class,Page<T> page,Sort sort,String column,Object[] values,String...columns){
//		Query query=this.getSortQuery(this.getColumnInValueQuery(this.getIncludeColumnQuery(null, columns), column, values),sort);
//		this.getPageT(mongoTemplate, query ,page, _class);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象不包含 columns 这几列
//	 * @param t
//	 * @param column
//	 * @param values
//	 * @param excludeColumns
//	 * @return
//	 */
//	public <T> void getTsByColumnsExcludeColumns(Class<T> t,Page<T> page,Sort sort,String column,Object[] values,String...excludeColumns){
//		getPageTByColumnsExcludeColumns(mongoTemplate,t,page,sort,column,values,excludeColumns);
//	}
//	
//	/**根据一列的值获取 文档对象，这些对象不包含 columns 这几列
//	 * @param mongoTemplate
//	 * @param _class
//	 * @param column
//	 * @param values
//	 * @param excludeColumns
//	 * @return
//	 */
//	public <T> void getPageTByColumnsExcludeColumns(MongoTemplate mongoTemplate,Class<T> _class,Page<T> page,Sort sort,String column,Object[] values,String...excludeColumns){
//		Query query=this.getSortQuery(this.getColumnInValueQuery(this.getExcludeColumnQuery(null, excludeColumns), column, values),sort);
//		this.getPageT(mongoTemplate, query,page, _class);
//	}
	
	
	
	
	
	
	
	/**
	 * @return
	 */
	public MongoTemplate getMongoTemplate(){
		return mongoTemplate;
	}
	
	
	/**获取一个实体类的集合名
	 * @param _class
	 * @return
	 */
	public static <T> String getTCollectionName(Class<? extends T> _class){
		return superDao.mongoTemplate.getCollectionName(_class);
	}
	
	
	/**获取一页的数据
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 */
	public <T> void getPageT(Query query,Page<T> page,Class<T> _class){
		
		String connectionName=mongoTemplate.getCollectionName(_class);
		
		getPageT(mongoTemplate,query,page,_class,connectionName);
	}
	
	/**获取一页的数据
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 */
	public <T> void getPageT(Query query,Page<T> page,Class<T> _class,String connectionName){
		getPageT(mongoTemplate,query,page,_class,connectionName);
	}
	
	/**获取一页的数据
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 */
	public <T> void getPageT(MongoTemplate mongoTemplate,Query query,Page<T> page,Class<T> _class){
		
		String connectionName=mongoTemplate.getCollectionName(_class);
		
		getPageT(mongoTemplate,query,page,_class,connectionName);
	}
	
	/**获取一页的数据
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 */
	public <T> void getPageT(MongoTemplate mongoTemplate,Query query,Page<T> page,Class<T> _class,String connectionName){
		
		query=getPageQuery(query,page);
		
		long totalCount=this.getQueryTotalCount(mongoTemplate, query,connectionName);
		
		page.setTotalCount(totalCount);
		
		if(page.getCurrentPage()<=page.getPageCount()){
			List<T> result= getAllT(mongoTemplate,query,_class,connectionName);
			page.setList(result);
		}
	}
	
	/**获取所有文档
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> List<T> getAllT(Query query,Class<T> _class){
		return getAllT(mongoTemplate,query,_class);
	}
	
	/**获取所有符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> List<T> getAllT(MongoTemplate mongoTemplate,Query query,Class<T> _class){
		
		String connectionName=mongoTemplate.getCollectionName(_class);
		
		return getAllT(mongoTemplate,query,_class,connectionName);
	}
	
	/**获取所有符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> List<T> getAllT(MongoTemplate mongoTemplate,Query query,Class<T> _class,String connectionName){
		
		long begin=System.currentTimeMillis();
		if(null == query){
			query=new Query();
		}
		String message=this.getQueryString(connectionName, query, "多个结果");
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.find(query, _class,connectionName));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	/**从数据库获取一个符合条件文档
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> T getOneT(Query query,Class<T> _class){
		return getOneT(mongoTemplate,query,_class);
	}
	
	/** 从数据库中获取一个符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> T getOneT(MongoTemplate mongoTemplate,Query query,Class<T> _class){
		String connectionName=mongoTemplate.getCollectionName(_class);
		return getOneT(mongoTemplate,query,_class,connectionName);
	}
	
	/** 从数据库中获取一个符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> T getOneT(MongoTemplate mongoTemplate,Query query,Class<T> _class,String connectionName){
		
		String message=this.getQueryString(connectionName, query, "一个结果");
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.findOne(query, _class,connectionName));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	/**获取该查询总的结果
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> long getQueryTotalCount(MongoTemplate mongoTemplate,Query query,String connectionName){
		if(null == mongoTemplate || null == query){
			return 0;
		}
		String message=this.getQueryString(connectionName, query, "条数");
		try {
			return printQueryExecuteTime(System.currentTimeMillis(),message,mongoTemplate.count(query, connectionName));
		} catch (Exception e) {
			queryException(e,message);
			return 0;
		}
	}
	
	/**获取该查询总的结果
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> long getQueryTotalCount(MongoTemplate mongoTemplate,Query query,Class<T> _class){
		
		if(null == _class){
			return 0;
		}
		String connectionName=this.getTCollectionName(_class);
		return this.getQueryTotalCount(mongoTemplate, query, connectionName);
	}
	
	/**获取查询总的结果
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> long getQueryTotalCount(Query query,Class<T> _class){
		return getQueryTotalCount(mongoTemplate,query,_class);
	}
	
	/**更新所有符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param update
	 * @param connectionName
	 * @return
	 */
	public <T> WriteResult updateAll(MongoTemplate mongoTemplate,Query query,Update update,String connectionName){
		
		if(null == mongoTemplate || null == query || null == update){
			return null;
		}
		String message=this.getQueryUpdateString(connectionName, query, update, "更新所有");
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.updateMulti(query, update, connectionName));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	/**更新所有符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param update
	 * @param _class
	 * @return
	 */
	public <T> WriteResult updateAll(MongoTemplate mongoTemplate,Query query,Update update,Class<T> _class){
		
		if(null == _class){
			return null;
		}
		String connectionName=mongoTemplate.getCollectionName(_class);
		
		return this.updateAll(mongoTemplate, query, update, connectionName);
	}
	
	public <T> WriteResult updateAll(Query query,Update update,Class<T> _class){
		return updateAll(mongoTemplate,query,update,_class);
	}
	
	/**更新符合条件的第一个文档
	 * @param query
	 * @param update
	 * @param _class
	 * @return
	 */
	public <T> WriteResult updateFirst(Query query,Update update,Class<T> _class){
		return updateFirst(mongoTemplate,query,update,_class);
	}
	
	/**更新符合条件的第一个文档
	 * @param mongoTemplate
	 * @param query
	 * @param update
	 * @param connectionName
	 * @return
	 */
	public <T> WriteResult updateFirst(MongoTemplate mongoTemplate,Query query,Update update,String connectionName){
		
		if(null == mongoTemplate || null == query || null == update){
			return null;
		}
		String message=this.getQueryUpdateString(connectionName, query, update, "一个结果");
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.updateFirst(query, update, connectionName));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	/** 更新第一个符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param update
	 * @param _class
	 * @return
	 */
	public <T> WriteResult updateFirst(MongoTemplate mongoTemplate,Query query,Update update,Class<T> _class){
		
		if(null == _class){
			return null;
		}
		String connectionName=mongoTemplate.getCollectionName(_class);
		WriteResult result = updateFirst(mongoTemplate,query, update, connectionName);
		
		return result;
	}
	
	public <T> WriteResult upsert(Query query,Update update,Class<T> _class){
		NullUtil.objectsIsNull(true,mongoTemplate,query,update,_class);
		String collectionName=mongoTemplate.getCollectionName(_class);
		return upsert(mongoTemplate,query,update,_class);
	}
	
	public <T> WriteResult upsert(MongoTemplate mongoTemplate,Query query,Update update,Class<T> _class){
		NullUtil.objectsIsNull(true,mongoTemplate,query,update,_class);
		String collectionName=mongoTemplate.getCollectionName(_class);
		return upsert(mongoTemplate,query,update,collectionName);
	}
	
	/**upsert
	 * @param montemplate
	 * @param query
	 * @param update
	 * @param _class
	 * @return
	 */
	public WriteResult upsert(MongoTemplate mongotemplate,Query query,Update update,String collectionName){
		NullUtil.objectsIsNull(true,mongoTemplate,query,update);
		String message=this.getQueryUpdateString(collectionName, query, update, "upsert");
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.upsert(query, update, collectionName));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	public CommandResult executeCommand(String command){
		return executeCommand(mongoTemplate,command);
	}
	
	public CommandResult executeCommand(MongoTemplate mongoTemplate,String command){
		
		String message="执行命令 "+command;
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.executeCommand(command));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	public <T> WriteResult remove(Query query,Class<T> _class){
		return remove(mongoTemplate,query,_class);
	}
	
	/**移除符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public <T> WriteResult remove(MongoTemplate mongoTemplate,Query query,Class<T> _class){
		
		if(null == mongoTemplate || null == query || null == _class){
			return null;
		}
		String collectionName=mongoTemplate.getCollectionName(_class);
		WriteResult result = remove(mongoTemplate,query,collectionName);
		
		return result;
	}
	
	/**移除符合条件的文档
	 * @param mongoTemplate
	 * @param query
	 * @param _class
	 * @return
	 */
	public WriteResult remove(MongoTemplate mongoTemplate,Query query,String connectionName){
		
		if(null == mongoTemplate || null == query || StringUtils.isEmpty(connectionName)){
			return null;
		}
		String message=this.getQueryString(connectionName, query, "删除");
		try {
			return this.printQueryExecuteTime(System.currentTimeMillis(), message, mongoTemplate.remove(query, connectionName));
		} catch (Exception e) {
			queryException(e,message);
			return null;
		}
	}
	
	/**新增一个对象
	 * @param t
	 * @param object
	 */
	public <T> void addOneT(T object){
		addOneT(mongoTemplate,object);
	}
	
	
	/**新增一个对象
	 * @param t
	 * @param object
	 */
	public <T> void addOneT(MongoTemplate mongoTemplate,T object){
		String collectionName=mongoTemplate.getCollectionName(object.getClass());
		addOneT(mongoTemplate,object,collectionName);
	}
	
	/**新增一个对象
	 * @param t
	 * @param object
	 */
	public <T> void addOneT(T object,String collectionName){
		addOneT(mongoTemplate,object,collectionName);
	}
	
	/**新增一个对象
	 * @param t
	 * @param object
	 */
	public <T> void addOneT(MongoTemplate mongoTemplate,T object,String collectionName){
		mongoTemplate.insert(object, collectionName);
	}
	
	
	
	
	
	
	
	/**新增多个对象
	 * @param t
	 * @param object
	 */
	public <T> void addAllT(Collection<T> object){
		addAllT(mongoTemplate,object);
	}
	
	/**新增多个对象
	 * @param t
	 * @param object
	 */
	public <T> void addAllT(MongoTemplate mongoTemplate,Collection<T> object){
		mongoTemplate.insertAll(object);
	}
	
	/**新增多个对象
	 * @param t
	 * @param object
	 */
	public <T> void addAllT(Collection<T> object,String collectionName){
		addOneT(mongoTemplate,object,collectionName);
	}
	
	/**新增多个对象
	 * @param t
	 * @param object
	 */
	public <T> void addAllT(MongoTemplate mongoTemplate,Collection<T> object,String collectionName){
		mongoTemplate.insert(object, collectionName);
	}
	
	
	
	
	
	
	
	
	
	
	/**获取包含分页信息的query
	 * @param query
	 * @param page
	 * @return
	 */
	public <T> Query getPageQuery(Query query,Page<T> page){
		if(null == query){
			query=new Query();
		}
		
		if(null == page){
			return query;
		}
		int begin = (page.getCurrentPage() - 1) * page.getPageSize();
		
		query.skip(begin).limit(page.getPageSize());
		
		return query;
	}
	
	/**获取包含排序信息的query
	 * @param query
	 * @param sort
	 * @return
	 */
	public Query getSortQuery(Query query,Sort sort){
		
		if(null == query){
			query=new Query();
		}
		
		if(null == sort){
			return query;
		}
		return query.with(sort);
	}
	
	/**获取包含一些条件的query
	 * @param query
	 * @param criterias
	 * @return
	 */
	public Query getCriteriasQuery(Query query,Criteria...criterias){
		if(null == query){
			query=new Query();
		}
		if(null == criterias){
			return query;
		}else if(criterias.length == 1){
			query.addCriteria(criterias[0]);
		}else{
			for(Criteria criteria:criterias){
				query.addCriteria(criteria);
			}
		}
		return query;
	}
	
	/**获取 列值包含在数组中query
	 * @param query
	 * @param column
	 * @param values
	 * @return
	 */
	public Query getColumnInValueQuery(Query query,String column,Object...values){
		if(null == query){
			query=new Query();
		}
		Criteria criteria=Criteria.where(column).in(values);
		query.addCriteria(criteria);
		return query;
	}
	
	/**获取包含某些字段的query
	 * @param query
	 * @param columns
	 * @return
	 */
	public Query getIncludeColumnQuery(Query query,String...columns){
		if(null == query){
			query=new Query();
		}
		if(null == columns){
			return query;
		}else if(columns.length == 1){
			query.fields().include(columns[0]);
		}else{
			for(String column:columns){
				query.fields().include(column);
			}
		}
		query.fields().include(AbstractDocument.COLUMN_CLASS);
		return query;
	}
	
	/** 获取不包含某些字段的query
	 * @param query
	 * @param columns
	 * @return
	 */
	public Query getExcludeColumnQuery(Query query,String...columns){
		if(null == query){
			query=new Query();
		}
		if(null == columns){
			return query;
		}else if(columns.length == 1){
			query.fields().exclude(columns[0]);
		}else{
			for(String column:columns){
				query.fields().exclude(column);
			}
		}
		return query;
	}
	
	/**获取不包含或包含某几列的查询条件，不包含优先级更高
	 * @param query
	 * @param needColumns
	 * @param notNeedColumns
	 * @return
	 */
	public Query getExcludeOrIncludeColumnQuery(Query query,String[] needColumns,String[] notNeedColumns){
		if(null != notNeedColumns){
			return this.getExcludeColumnQuery(query, notNeedColumns);
		}else{
			return this.getIncludeColumnQuery(query, needColumns);
		}
	}
	
	/** 获取 is 查询query
	 * @param query
	 * @param column
	 * @param value
	 * @return
	 */
	public Query getIsQuery(Query query,String column,Object value){
		if(null == query){
			query=new Query();
		}
		if(null == value){
			return query;
		}
		Criteria criteria=Criteria.where(column).is(value);
		query.addCriteria(criteria);
		return query;
	}
	
	/**获取多个条件的query
	 * @param query
	 * @param criterias
	 * @return
	 */
	public Query getCriteriaQuery(Query query,Criteria...criterias){
		if(null == query){
			query=new Query();
		}
		if(null == criterias){
			return query;
		}
		for(Criteria c:criterias){
			query.addCriteria(c);
		}
		return query;
	}
	
	
	
	/**获取 $set 操作的update
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getSetUpdate(Update update,String key,Object value){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.set(key, value);
		
		return update;
	}
	
	/**获取 $unset 操作的update
	 * @param update
	 * @param key
	 * @return
	 */
	public Update getUnSetUpdate(Update update,String key){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.unset(key);
		
		return update;
	}
	
	/**获取 $push 操作的update
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getPushUpdate(Update update,String key,Object value){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.push(key, value);
		
		return update;
	}
	
	/**获取 $pushall 操作的update
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getPushAllUpdate(Update update,String key,Object[] value){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.pushAll(key, value);
		
		return update;
	}
	
	/**获取 $pull 操作的update
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getPullUpdate(Update update,String key,Object value){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.pull(key, value);
		
		return update;
	}
	
	/**获取 $pullall 操作的update
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getPullAllUpdate(Update update,String key,Object[] value){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.pullAll(key, value);
		
		return update;
	}
	
	/**获取 $pop 操作的update,默认顶端
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getPopUpdate(Update update,String key){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.pop(key, Update.Position.FIRST);
		return update;
	}
	
	/**获取 $pop 操作的update
	 * @param update
	 * @param key
	 * @param value
	 * @return
	 */
	public Update getPopUpdate(Update update,String key,Update.Position position){
		
		if(null == update){
			update=new Update();
		}
		if(StringUtils.isEmpty(key)){
			return update;
		}
		update.pop(key, position);
		return update;
	}
	
	/**将parameter传入的参数生成查询条件，只限is查询
	 * @param parameter
	 * @return
	 */
	public Query getParameterQuery(Map<String,? extends Object> parameter){
		Query query=new Query();
		if(null != parameter){
			for(String key:parameter.keySet()){
				query=superDao.getIsQuery(query, key, parameter.get(key));
			}
		}
		return query;
	}
	
	/**打印执行时间
	 * @param startTime
	 * @param message
	 * @param object
	 */
	private <T> T printQueryExecuteTime(long startTime,String message,T object) throws Exception{
		long endTime=System.currentTimeMillis();
		if(StringUtils.isEmpty(message)){
			logger.debug("耗费时间 "+(endTime-startTime)+" 毫秒");
		}else{
			logger.debug(message+" 耗费时间 "+(endTime-startTime)+" 毫秒");
		}
		return object;
	}
	
	private String getQueryString(String connectionName,Query query,String message){
		return new StringBuilder().append("从 ").append(connectionName).append(" 查询 ").append(query.toString()).append(" ").append(message).toString();
	}
	
	private String getQueryUpdateString(String connectionName,Query query,Update update,String message){
		return new StringBuilder().append("从 ").append(connectionName).append(" 查询 ").append(" ").append(query.toString()).append(" 并更新 ").append(update.toString()).toString();
	}
	
	private void queryException(Exception e,String message){
		logger.error(message+","+e.getMessage());
		e.printStackTrace();
	}
}
